package de.Hero.clickgui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import Squad.Squad;
import Squad.base.Category;
import Squad.base.Module;
import de.Hero.clickgui.elements.Element;
import de.Hero.clickgui.elements.ModuleButton;
import de.Hero.clickgui.elements.menu.ElementSlider;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;

public class ClickGUI extends GuiScreen {
	public static ArrayList<Panel> panels;
	public static ArrayList<Panel> rpanels;
	private ModuleButton mb = null;

	/*
	 * Konstrukor sollte nur einmal aufgerufen werden => in der MainMethode des
	 * eigenen Codes hier Client.startClient() das GUI wird dann so geffnet:
	 * mc.displayGuiScreen(Client.clickgui); this.setToggled(false); das Module
	 * wird sofort wieder beendet damit nchstes mal nicht 2mal der z.B.
	 * 'RSHIFT' Knopf gedrckt werden muss
	 */
	public ClickGUI() {
		FontUtils.setupFontUtils();
		panels = new ArrayList<Panel>();
		float pwidth = 80;
		float pheight = 15;
		float px = 10;
		float py = 10;
		float pyplus = pheight + 10;

		/*
		 * Zum Sortieren der Panels einfach die Reihenfolge im Enum ndern ;)
		 */
		for (final Category c : Category.values()) {
			String title = Character.toUpperCase(c.name().toLowerCase().charAt(0))
					+ c.name().toLowerCase().substring(1);
			ClickGUI.panels.add(new Panel(title, px, py, pwidth, pheight, false) {
				@Override
				public void setup() {
					for (Module m : Squad.instance.moduleManager.modules) {
						if (!m.getCategory().equals(c))
							continue;
						this.Elements.add(new ModuleButton(m, this));
					}
				}
			});
			py += pyplus;
		}

		/*
		 * Wieso nicht einfach rpanels = panels; Collections.reverse(rpanels);
		 * Ganz eifach: durch diese Zuweisung wird rpanels einfach nur eine
		 * Weiterleitung zu panels, was mit 'Collections.reverse(rpanels);'
		 * nicht ganz funktionieren wrde. Und da die Elemente nur
		 * 'rberkopiert' werden gibt es keine Probleme ;)
		 */
		rpanels = new ArrayList<Panel>();
		for (Panel p : panels) {
			rpanels.add(p);
		}
		Collections.reverse(rpanels);

	}

	@Override
	public void drawScreen(int mouseX, int mouseY, float partialTicks) {
		/*
		 * Panels und damit auch Buttons rendern. panels wird NUR hier im Code
		 * verwendet, da das zuletzt gerenderte Panel ganz oben ist Auch wenn es
		 * manchmal egal wre ob panels/rpanels benutzt wird habe ich mich
		 * einfach mal dazu entschieden, einfach weil es einfacher ist nur
		 * einmal panels zu benutzen
		 */
		for (Panel p : panels) {
			p.drawScreen(mouseX, mouseY, partialTicks);
		}

		ScaledResolution s = new ScaledResolution(Minecraft.getMinecraft(), Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight);
		/*
		 * Kleines Watermark ;>
		 */
		GL11.glPushMatrix();
		FontUtils.drawStringWithShadow("by HeroCode <3.",
				(s.getScaledWidth() - Minecraft.getMinecraft().fontRendererObj.getStringWidth("by HeroCode <3")),
				(s.getScaledHeight() - Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT), 0xff11F86B);
		GL11.glPopMatrix();

		mb = null;
		/*
		 * berprfen ob ein Button listening == true hat, wenn ja, dann soll
		 * nicht mehr gesucht werden, nicht dass 1+ auf listening steht...
		 */
		listen: for (Panel p : rpanels) {
			if (p != null && p.visible && p.extended && p.Elements != null && p.Elements.size() > 0) {
				for (ModuleButton e : p.Elements) {
					if (e.listening) {
						mb = e;
						break listen;
					}
				}
			}
		}

		/*
		 * Settings rendern. Da Settings ber alles gerendert werden soll,
		 * abgesehen vom ListeningOverlay werden die Elements von hier aus fast
		 * am Schluss gerendert
		 */
		settings: for (Panel panel : ClickGUI.rpanels) {
			if (panel.extended && panel.visible && panel.Elements != null) {
				for (ModuleButton b : panel.Elements) {
					if (b.extended) {
						float off = 0;
						for (Element e : b.menuelements) {
							e.offset = off;
							off += e.height + 1;
							e.drawScreen(mouseX, mouseY, partialTicks);
						}
						break settings;
					}
				}
			}

		}

		/*
		 * Wenn mb != null ist => ein Button listening == true dann wird das
		 * Overlay gerendert mit ein paar Informationen.
		 */
		if (mb != null) {
			drawRect(0, 0, this.width, this.height, 0x88101010);
			GL11.glPushMatrix();
			GL11.glTranslatef(s.getScaledWidth() / 2, s.getScaledHeight() / 2, 0.0F);
			GL11.glScalef(4.0F, 4.0F, 0F);
			FontUtils.drawTotalCenteredStringWithShadow("Listening...", 0, -10, 0xffffffff);
			GL11.glScalef(0.5F, 0.5F, 0F);
			FontUtils.drawTotalCenteredStringWithShadow(
					"Press 'ESCAPE' to unbind " + mb.mod.name
							+ (mb.mod.getKeyBind() > -1 ? " (" + Keyboard.getKeyName(mb.mod.getKeyBind()) + ")" : ""),
					0, 0, 0xffffffff);
			GL11.glPopMatrix();
		}

		/*
		 * Nicht bentigt, aber es ist so einfach sauberer ;) Und ohne diesen
		 * call knnen keine GUIButtons/andere Elemente gerendert werden
		 */
		super.drawScreen(mouseX, mouseY, partialTicks);
	}

	@Override
	public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
		/*
		 * Damit man nicht nochmal den Listeningmode aktivieren kann, wenn er
		 * schon aktiviert ist
		 */
		if (mb != null)
			return;

		/*
		 * Bentigt damit auch mit Elements interagiert werden kann besonders zu
		 * beachten ist dabei, dass zum einen rpanels aufgerufen wird welche
		 * eine Eigenstndige Kopie von panels ist, genauer oben erklrt Also
		 * rpanels damit zuerst das panel 'untersucht' wird, dass als letztes
		 * gerendert wurde => Ganz oben ist! sodass der Nutzer nicht mit dem
		 * Unteren interagiern kann, weil er es wohl nicht will. Und damit nicht
		 * einfach mit Panels anstatt Elements interagiert wird werden hier nur
		 * die Settings untersucht. Und wenn wirklich interagiert wurde, dann
		 * endet diese Methode hier. Das ist auch in anderen Loops zu beobachten
		 */
		for (Panel panel : ClickGUI.rpanels) {
			if (panel.extended && panel.visible && panel.Elements != null) {
				for (ModuleButton b : panel.Elements) {
					if (b.extended) {
						for (Element e : b.menuelements) {
							if (e.mouseClicked(mouseX, mouseY, mouseButton))
								return;
						}
					}
				}
			}
		}

		/*
		 * Bentigt damit mit ModuleButtons interagiert werden kann und Panels
		 * 'gegriffen' werden knnen
		 */
		for (Panel p : rpanels) {
			if (p.mouseClicked(mouseX, mouseY, mouseButton))
				return;
		}

		/*
		 * Nicht bentigt, aber es ist so einfach sauberer ;)
		 */
		try {
			super.mouseClicked(mouseX, mouseY, mouseButton);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void mouseReleased(int mouseX, int mouseY, int state) {
		/*
		 * Damit man nicht nochmal den Listeningmode aktivieren kann, wenn er
		 * schon aktiviert ist
		 */
		if (mb != null)
			return;

		/*
		 * Eigentlich nur fr die Slider bentigt, aber durch diesen Call
		 * erfhrt jedes Element, wenn z.B. Rechtsklick losgelassen wurde
		 */
		for (Panel panel : ClickGUI.rpanels) {
			if (panel.extended && panel.visible && panel.Elements != null) {
				for (ModuleButton b : panel.Elements) {
					if (b.extended) {
						for (Element e : b.menuelements) {
							e.mouseReleased(mouseX, mouseY, state);
						}
					}
				}
			}
		}

		/*
		 * Bentigt damit Slider auch losgelassen werden knnen und nicht immer
		 * an der Maus 'festkleben' :>
		 */
		for (Panel p : rpanels) {
			p.mouseReleased(mouseX, mouseY, state);
		}

		/*
		 * Nicht bentigt, aber es ist so einfach sauberer ;)
		 */
		super.mouseReleased(mouseX, mouseY, state);
	}

	@Override
	protected void keyTyped(char typedChar, int keyCode) {
		/*
		 * Bentigt fr die Keybindfunktion
		 */
		for (Panel p : rpanels) {
			if (p != null && p.visible && p.extended && p.Elements != null && p.Elements.size() > 0) {
				for (ModuleButton e : p.Elements) {
					try {
						if (e.keyTyped(typedChar, keyCode))
							return;
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		}

		/*
		 * keyTyped in GuiScreen MUSS aufgerufen werden, damit man mit z.B.
		 * ESCAPE aus dem GUI gehen kann
		 */
		try {
			super.keyTyped(typedChar, keyCode);
		} catch (IOException e2) {
			e2.printStackTrace();
		}
	}

	@Override
	public void initGui() {
		/*
		 * Start blur
		 */
		}

	@Override
	public void onGuiClosed() {
		/*
		 * End blur
		 */
			
		/*
		 * Sliderfix
		 */
		for (Panel panel : ClickGUI.rpanels) {
			if (panel.extended && panel.visible && panel.Elements != null) {
				for (ModuleButton b : panel.Elements) {
					if (b.extended) {
						for (Element e : b.menuelements) {
							if (e instanceof ElementSlider) {
								((ElementSlider) e).dragging = false;
							}
						}
					}
				}
			}
		}
	}

	public void closeAllSettings() {
	}
}
